/*
 * Copyright (C) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "custom_file_type_parser.h"

using namespace ImageKnifePro;
namespace ImageKnifeTest {

CustomDecodeImageSource::CustomDecodeImageSource(uint8_t *buffer, uint32_t length)
{
    if (OH_ImageSourceNative_CreateFromData(buffer, length, &source_) != IMAGE_SUCCESS) {
        source_ = nullptr;
    }
}

OH_ImageSourceNative *CustomDecodeImageSource::GetImageSourceNative() const
{
    return source_;
}

void GetImageFileInfoFromSource(FileTypeInfo *fileTypeInfo, OH_ImageSourceNative *source)
{
    if (source == nullptr) {
        return;
    }

    // 获取图片信息
    OH_ImageSource_Info *imageInfo;
    OH_ImageSourceInfo_Create(&imageInfo);
    OH_ImageSourceNative_GetImageInfo(source, 0, imageInfo);
    OH_ImageSourceInfo_GetWidth(imageInfo, &fileTypeInfo->width);
    OH_ImageSourceInfo_GetHeight(imageInfo, &fileTypeInfo->height);
    OH_ImageSourceInfo_Release(imageInfo);

    OH_ImageSourceNative_GetFrameCount(source, &fileTypeInfo->frameCount);
    if (fileTypeInfo->frameCount > 1) {
        int *delayTimeList = new int[fileTypeInfo->frameCount];
        OH_ImageSourceNative_GetDelayTimeList(source, delayTimeList, fileTypeInfo->frameCount);

        auto deleter = [](void *data) {
            int *timeList = static_cast<int *>(data);
            delete [] timeList;
        };
        fileTypeInfo->delayTimeList = std::shared_ptr<int []>(delayTimeList, deleter);
    }
}

std::shared_ptr<FileTypeInfo> CustomFileTypeParser::ParseFileTypeInfo(uint8_t *buffer, uint32_t length,
                                                                      std::shared_ptr<DecodeImageSource> imageSource)
{
    auto fileTypeInfo = std::make_shared<FileTypeInfo>();
    // 使用webp模拟自定义的文件格式
    static std::vector<uint8_t> customWebpSignature = {0x52, 0x49, 0x46, 0x46};
    if (length < customWebpSignature.size()) {
        return nullptr;
    }

    for (int i = 0; i < customWebpSignature.size(); i++) {
        if (buffer[i] != customWebpSignature[i]) {
            fileTypeInfo->format = ImageFormat::UNKNOWN;
            return fileTypeInfo;
        }
    }
    fileTypeInfo->format = ImageFormat::CUSTOM_FORMAT;
    fileTypeInfo->customFormat = "Custom Webp";
    auto source = std::dynamic_pointer_cast<CustomDecodeImageSource>(imageSource);
    if (source != nullptr) {
        GetImageFileInfoFromSource(fileTypeInfo.get(), source->GetImageSourceNative());
    }

    return fileTypeInfo;
}

std::shared_ptr<DecodeImageSource> CustomFileTypeParser::CreateDecodeImageSource(uint8_t *buffer, uint32_t length)
{
    return std::make_shared<CustomDecodeImageSource>(buffer, length);
}


static napi_value RegisterCustomFileTypeParser(napi_env env, napi_callback_info info)
{
    auto customFileTypeParser = std::make_shared<CustomFileTypeParser>();
    ImageKnife::GetInstance().SetFileTypeParser(customFileTypeParser);
    return nullptr;
}

napi_value CustomFileTypeParserSetupTests(napi_env env, napi_value &exports)
{
    napi_property_descriptor desc[] = {
        { "registerCustomFileTypeParser", nullptr, RegisterCustomFileTypeParser,
            nullptr, nullptr, nullptr, napi_default, nullptr }
    };
    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);

    return exports;
}

}